//////////////////////////////// code voor strings xy in mem /////////////////

(*
type
  TMatrixStringItem = record
    fString: string;
    fObject: TObject;
  end;

  TMatrixStringItemArray = array of TMatrixStringItem;

  TMatrixStrings = class
  private
    fMatrix: TCustomSuperMatrix;
//    fData: array of TOpenStringArray;
    fItems: array of TMatrixStringItemArray;
    procedure CheckCoord(aCol, aRow: integer);
    function CheckColRow(aCol, aRow: integer): boolean;
    procedure EnsureColRow(aCol, aRow: integer);
    procedure InternalDeleteCol(aCol, aRow: integer);
    procedure InternalInsertCol(aCol, aRow: integer);
    procedure InternalDeleteRow(aRow: integer);
    procedure InternalInsertRow(aRow: integer);
    procedure InternalSetString(aCol, aRow: integer; const S: string);
  public
    constructor Create(aMatrix: TCustomSuperMatrix);
    destructor Destroy; override;
    procedure MoveColumn(A, B: integer);
    procedure MoveRow(A, B: integer);
    procedure SetString(aCol, aRow: integer; const S: string);
    function GetString(aCol, aRow: integer): string;
    procedure SetObject(aCol, aRow: integer; const O: TObject);
    function GetObject(aCol, aRow: integer): TObject;
    function LastColCount: integer;
    function GetRowCount: integer;
    procedure InsertRow(R: integer);
    procedure AssignCol(aCol: integer; const aStrings: TStrings);
    procedure Clear;
    //property Objects;
  end;

implementation

{ TMatrixStrings }

function TMatrixStrings.CheckColRow(aCol, aRow: integer): boolean;
begin
{  Result := (Length(fData) >= aRow + 1) and
            (Length(fData[aRow]) >= aCol + 1); }
  Result := (Length(fItems) >= aRow + 1) and
            (Length(fItems[aRow]) >= aCol + 1);
end;

procedure TMatrixStrings.CheckCoord(aCol, aRow: integer);
begin
  if (aCol < 0) or (aRow < 0) then
    raise Exception.CreateFmt('ColRow fout in ' + ClassName + ' (%d, %d) ', [aCol, aRow]);
end;

constructor TMatrixStrings.Create(aMatrix: TCustomSuperMatrix);
begin
  inherited Create;
  fMatrix := aMatrix;
end;

destructor TMatrixStrings.Destroy;
begin
//  fData := nil;
  fItems := nil;
  inherited Destroy;
end;

procedure TMatrixStrings.EnsureColRow(aCol, aRow: integer);
var
  L, Delta: integer;
begin
  CheckCoord(aCol, aRow);

  { smart allocation }
{  L := Length(fData);
  if L > 64 then Delta := L div 4 else
    if L > 8 then Delta := 16 else
      Delta := 4;
  if L < aRow + 1 then
  begin
    SetLength(fData, aRow + 1 + Delta);
  end;
  if Length(fData[aRow]) < aCol + 1 then
    SetLength(fData[aRow], aCol + 1); }

  { smart allocation }
  L := Length(fItems);
  if L > 64 then Delta := L div 4 else
    if L > 8 then Delta := 16 else
      Delta := 4;
  if L < aRow + 1 then
  begin
    SetLength(fItems, aRow + 1 + Delta);
    // initialiseren op nil nodig?
  end;
  if Length(fItems[aRow]) < aCol + 1 then
    SetLength(fItems[aRow], aCol + 1);
end;

function TMatrixStrings.GetObject(aCol, aRow: integer): TObject;
begin
  if CheckColRow(aCol, ARow) then Result := fItems[aRow, aCol].fObject else Result := nil;
end;

function TMatrixStrings.GetString(aCol, aRow: integer): string;
begin
//  if CheckColRow(aCol, ARow) then Result := fData[aRow, aCol] else Result := '';
  if CheckColRow(aCol, ARow) then Result := fItems[aRow, aCol].fString else Result := '';
end;

procedure TMatrixStrings.InternalDeleteCol(aCol, aRow: integer);
var
  TempItems: TMatrixStringItemArray;
  i: integer;
begin
  TempItems := Copy(fItems[aRow]);
  for i := 0 to aCol - 1 do
    fItems[aRow][i] := TempItems[i];
  for i := aCol to Length(TempItems) - 2 do
    fItems[aRow][i] := TempItems[i + 1];
  SetLength(fItems[aRow], Length(fItems[aRow]) - 1);
end;

procedure TMatrixStrings.InternalInsertCol(aCol, aRow: integer);
var
  TempItems: TMatrixStringItemArray;
  i: integer;
begin
  TempItems := Copy(fItems[aRow]);
  SetLength(fItems[aRow], Length(fItems[aRow]) + 1);
  for i := 0 to aCol - 1 do
    fItems[aRow][i] := TempItems[i];
  for i := aCol + 1 to Length(TempItems) do
    fItems[aRow][i] := TempItems[i - 1];
end;

procedure TMatrixStrings.InternalDeleteRow(aRow: integer);
var
  TempItems: TMatrixStringItemArray;
  i: integer;
begin
{  TempItems := Copy(fItems[aRow]);
  for i := 0 to aCol - 1 do
    fItems[aRow][i] := TempItems[i]; }
  for i := aRow to Length(fItems) - 2 do
    fItems[i] := fItems[i + 1];
  SetLength(fItems, Length(fItems) - 1);
end;

procedure TMatrixStrings.InternalInsertRow(aRow: integer);
var
  TempItems: TMatrixStringItemArray;
  t,i: integer;

begin
//  EnsureColRow(0, GetRowCount + 1);

//  t:=gettickcount;
  for i := GetRowCount - 1 downto aRow + 1 do
    fItems[i] := fItems[i - 1];

//  SetLength(

  SetLength(fItems[aRow], 0);
  //for i := 0 to Length(fItems[aRow]) - 1 do
    //fItems[aRow][i].fstring := '';
{  t:=gettickcount-t;
  logon:=true;
  Log([t]);
  logon:=false;}




(*  TempItems := Copy(fItems[aRow]);
  SetLength(fItems[aRow], Length(fItems[aRow]) + 1);
  for i := 0 to aCol - 1 do
    fItems[aRow][i] := TempItems[i];
  for i := aCol + 1 to Length(TempItems) do
    fItems[aRow][i] := TempItems[i - 1]; *)
end;

function TMatrixStrings.LastColCount: integer;
begin
  if GetRowCount > 0 then
    Result := Length(fItems[GetRowCount - 1])
  else
    Result := 0;
end;

function TMatrixStrings.GetRowCount: integer;
begin
  Result := Length(fItems);
end;

procedure TMatrixStrings.MoveColumn(A, B: integer);
var
  y, x, GridCols, MaxCol: integer;
  Adjust, DoCopy: boolean;
  S: string;
begin
  if fMatrix <> nil then GridCols := THackedMatrix(fMatrix).ColCount else GridCols := 0;
  MaxCol := Max(A, B);
  for y := 0 to Length(fItems) - 1 do
  begin
    EnsureColRow(MaxCol, y);
    S := fItems[y][A].fString;
    InternalDeleteCol(A, y); { langzaam! }
    InternalInsertCol(B, y); { langzaam! }
    fItems[y][B].fString := S;
  end;
end;

procedure TMatrixStrings.MoveRow(A, B: integer);
begin
  if B <> -1 then
  begin
//    InternalDeleteRow(A);
    InternalInsertRow(A);
  end;
  
      
//  else  
end;

procedure TMatrixStrings.SetObject(aCol, aRow: integer; const O: TObject);
begin
  EnsureColRow(aCol, aRow);
  fItems[aRow, aCol].fObject := O;
  if fMatrix <> nil then
    fMatrix.SafeInvalidateCell(aCol, aRow);
end;

procedure TMatrixStrings.SetString(aCol, aRow: integer; const S: string);
begin
  EnsureColRow(aCol, aRow);
//  fData[aRow, aCol] := S;
  fItems[aRow, aCol].fString := S;
  UniqueString(fItems[aRow, aCol].fString);
  if fMatrix <> nil then
    fMatrix.SafeInvalidateCell(aCol, aRow);
end;

procedure TMatrixStrings.InternalSetString(aCol, aRow: integer; const S: string);
begin
  fItems[aRow, aCol].fString := S;
end;

procedure TMatrixStrings.Clear;
begin
  SetLength(fItems, 0);
  if fMatrix <> nil then
    fMatrix.Invalidate;
end;

procedure TMatrixStrings.AssignCol(aCol: integer; const aStrings: TStrings);
var
  i: integer;
begin
  EnsureColRow(aCol, aStrings.Count);
  fMatrix.PaintLock;
  try
    for i := 0 to aStrings.Count - 1 do
      SetString(aCol, i, aStrings[i])
  finally
    fMatrix.PaintUnlock;
  end;
end;

procedure TMatrixStrings.InsertRow(R: integer);
begin
  InternalInsertRow(R);
end;

end.
